package org.brisling.mobile.config;

import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.brisling.common.util.RSAUtils;

/**
 * 
 * <p>Title: RSAConfig</p>
 * <p>Description: 移动端密钥配置管理</p>
 * <p>Company: tongking</p>
 * @author jackson wang
 * @since 1.0
 * @version 1.0
 * @date 2017年5月15日 上午12:49:45
 */
public class RSAConfig {

	private static RSAConfig c = null;
	//初始密钥对（请求后密钥对迁移到已请求密钥对中）
	private static Map<String,Map<PublicKey, PrivateKey>> initRsaMap = new HashMap<String,Map<PublicKey, PrivateKey>>();
	
	
	//初始密钥对（请求后密钥对迁移到已请求密钥对中）
	private static Map<String,Map<PublicKey, PrivateKey>> verifyRsaMap = new HashMap<String,Map<PublicKey, PrivateKey>>();
	
	private RSAConfig(){
		initKeys(initRsaMap,100);
	}
	
	
	/*
	 * 初始化密钥对缓存池
	 */
	private static void initKeys(Map<String,Map<PublicKey, PrivateKey>> keymap, Integer times){
		
		Integer _times = times==null?100:times;
		
		//密钥对数量少于10，增加密钥池缓存数量
		Map<String, Map<PublicKey, PrivateKey>>  newMap = new HashMap<String, Map<PublicKey, PrivateKey>>();
		try {
			keymap.putAll(RSAUtils.initKeys(newMap, _times));
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/*
	 * 单例类获取实例
	 */
	public static RSAConfig getInstance(){
		if(c==null){
			c = new RSAConfig();
		}
		return c;
	}
	
	/**
	 * 获取和设置初始密钥对
	 * @return
	 */
	public static Map<String,Map<PublicKey, PrivateKey>> getInitRsaMap() {
		getInstance();
		return initRsaMap;
	}

	public static void setInitRsaMap(Map<String,Map<PublicKey, PrivateKey>> initRsaMap) {
		getInstance();
		RSAConfig.initRsaMap = initRsaMap;
	}

	/**
	 * 获取初始化密钥对
	 * @param keycode	密钥对代码
	 * @return
	 */
	public static Map<PublicKey, PrivateKey> getInitKeyPaire(String keycode){
		
		getInstance();
		if(initRsaMap.containsKey(keycode)){
			return initRsaMap.get(keycode);
		}
		return null;
	}
	
	/**
	 * 删除初始化密钥对
	 * @param keycode	密钥对代码
	 * @return
	 */
	public static Boolean removeInitKeyPaire(String keycode){
		
		getInstance();
		if(initRsaMap.containsKey(keycode)){
			initRsaMap.remove(keycode);
			return true;
		}
		return false;
	}
	/**
	 * 获取和设置已请求密钥对
	 * @return
	 */
	public static Map<String,Map<PublicKey, PrivateKey>> getVerifyRsaMap() {
		return verifyRsaMap;
	}

	public static void setVerifyRsaMap(Map<String,Map<PublicKey, PrivateKey>> verifyRsaMap) {
		RSAConfig.verifyRsaMap = verifyRsaMap;
	}

	/**
	 * 获取已请求密钥对
	 * @param keycode	密钥对代码
	 * @return
	 */
	public static Map<PublicKey, PrivateKey> getVerifyKeyPaire(String keycode){
		
		getInstance();
		if( verifyRsaMap.containsKey(keycode)){
			return verifyRsaMap.get(keycode);
		}
		return null;
	}
	
	/**
	 * 获取使用中密钥对的私钥
	 * @param code	密钥对代码
	 * @return
	 */
	public static PrivateKey getVerifyPrivateKey(String code){
		
		if(code!=null){
			Map<PublicKey, PrivateKey> keypaire = RSAConfig.getVerifyKeyPaire(code);
			if(keypaire!=null && !keypaire.isEmpty()){
				PrivateKey prikey = RSAConfig.getPrivateKey(keypaire);
				return prikey;
			}
		}
		return null;
	}
	/** 
	 * 获取指定密钥对的私钥
	 * @param keypaire	密钥对	 * 
	 * @return
	 */
	public static PrivateKey getPrivateKey(Map<PublicKey, PrivateKey> keypaire){
		
				
		if(keypaire!=null && keypaire.size()==1){
			Iterator<Map.Entry<PublicKey, PrivateKey>>  ite = keypaire.entrySet().iterator();
			
			if(ite!=null && ite.hasNext()){
				Map.Entry<PublicKey, PrivateKey> entry = ite.next();
				if(entry!=null){
					return entry.getValue();
				}
			}
		}
		return null;
		
	}
	
	/**
	 * 获取指定密钥对的公钥
	 * @param keypaire	密钥对	 * 
	 * @return
	 */
	public static PublicKey getPublicKey(Map<PublicKey, PrivateKey> keypaire){
		
				
		if(keypaire!=null && keypaire.size()==1){
			Iterator<Map.Entry<PublicKey, PrivateKey>>  ite = keypaire.entrySet().iterator();
			
			if(ite!=null && ite.hasNext()){
				Map.Entry<PublicKey, PrivateKey> entry = ite.next();
				if(entry!=null){
					return entry.getKey();
				}
			}
		}
		return null;
		
	}
	
	
	/**
	 * 删除使用中密钥对
	 * @param keycode	密钥对代码
	 * @return
	 */
	public static Boolean addVerifyKeyPaire(String keycode,Map<PublicKey, PrivateKey> keypair){
		
		getInstance();
		if(!verifyRsaMap.containsKey(keycode)){
			verifyRsaMap.put(keycode, keypair);
			return true;
		}
		return false;
	}
	/**
	 * 删除使用中密钥对
	 * @param keycode	密钥对代码
	 * @return
	 */
	public static Boolean removeVerifyKeyPaire(String keycode){
		
		getInstance();
		if(verifyRsaMap.containsKey(keycode)){
			verifyRsaMap.remove(keycode);
			return true;
		}
		return false;
	}
	
	/**
	 * 获取未使用的密钥对
	 * @return
	 */
	public static String getInitKey(){
		
		getInstance();
		//返回密钥对键值代码
		String retcode = null;
		
		
		
		//判断密钥对数量
		if(initRsaMap.size()<=10){
			
			initKeys(initRsaMap,50);
		}
		
		//判断缓存密钥池是否为空
		if(initRsaMap.size()>0){
			
			//获取密钥对entry			
			Iterator<Map.Entry<String, Map<PublicKey, PrivateKey>>> iteCode = initRsaMap.entrySet().iterator();
			if(iteCode!=null && iteCode.hasNext()){
				
				//迭代获取密钥对uuid代码
				Map.Entry<String, Map<PublicKey, PrivateKey>>  entry = iteCode.next();
				retcode = entry.getKey();
				
				if( (retcode!=null) && (retcode.trim().length()>0) ){
					
					//使用中密钥对缓存池增加密钥对
					RSAConfig.addVerifyKeyPaire(retcode, entry.getValue());
					//初始化密钥对缓存池删除密钥对
					RSAConfig.removeInitKeyPaire(retcode);
								
				}
			}
		}
		
		
		return retcode;
	}
	
	/**
	 * 根据密钥对代码，获取私钥对数据进行解密，并根据密钥重用标志判断是否保留密钥对
	 * @param pk	公钥
	 * @param data	加密数据
	 * @param isReused	密钥是否重用标志
	 * @return	String 解密后的数据
	 */
	public static String decrptData(String keycode,String data,Boolean isReused){
		
		//初始化是否重复利用密钥对
		boolean _reuse = isReused==null?false:isReused;
		
		//解密数据返回值
		String ret = null;
		
		if(verifyRsaMap!=null && verifyRsaMap.size()>0 ){
			if(verifyRsaMap.containsKey(keycode)){
					
				//获取密钥对代码所对应密钥对
				Map<PublicKey,PrivateKey> keypaire = verifyRsaMap.get(keycode);
				Iterator<Map.Entry<PublicKey, PrivateKey>>  ite = keypaire.entrySet().iterator();
				if( (ite!=null) && (ite.hasNext()) ){
					
					//获取密钥对代码所对应私钥
					PrivateKey _prikey = ite.next().getValue();
					if(_prikey instanceof RSAPrivateKey){
						RSAPrivateKey priKey=(RSAPrivateKey)_prikey;
						
						try {
						//用私钥解密数据
							ret = RSAUtils.decryptByPrivateKey(data,priKey);
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}	
						//判断是否重用密钥对
						if(!_reuse)
							verifyRsaMap.remove(keycode);
					}
				}
				
			}
		}
		
		return ret;
	}
	
	
}
